#include "ZPackageZip.h"
#include "unzip/unzip.h"


namespace ZuiLib
{

ZPackageZip::ZPackageZip(void)
	:m_zip(NULL)
{
}


ZPackageZip::~ZPackageZip(void)
{
	Close();
}

bool ZPackageZip::Open(const char* file)
{
	Close();
	m_zip = unzOpen(file);
	return m_zip != NULL;
}

bool ZPackageZip::Open(ZBufferPtr buffer)
{
	Close();

	if(buffer)
		m_zip = unzOpenBuffer(buffer->data(), buffer->size());

	if(m_zip)
		m_buffer = buffer;

	return m_zip != NULL;
}


void ZPackageZip::Close()
{
	if (m_zip)
	{
		unzClose(m_zip);
		m_zip = NULL;
		m_buffer = NULL;
	}
}


bool ZPackageZip::GotoFirstFile()
{
	if (m_zip)
		return unzGoToFirstFile(m_zip) == UNZ_OK;
	else
		return false;
}


bool ZPackageZip::GotoNextFile()
{
	if (m_zip)
		return unzGoToNextFile(m_zip) == UNZ_OK;
	else
		return false;
}

bool ZPackageZip::LocateFile(const char *szFileName, int iCaseSensitivity)
{
	if (m_zip)
		return unzLocateFile(m_zip,szFileName,iCaseSensitivity) == UNZ_OK;
	else
		return false;
}


bool ZPackageZip::GetFilePos(FilePos* pos)
{
	if (m_zip)
		return unzGetFilePos(m_zip, (unz_file_pos*)pos) == UNZ_OK;
	else
		return false;
}

bool ZPackageZip::SetFilePos(const FilePos* pos)
{
	if (m_zip)
		return unzGoToFilePos(m_zip, (unz_file_pos*)pos) == UNZ_OK;
	else
		return false;
}

ZString ZPackageZip::CurrentFileName()
{
	char nameBuf[128];
	if (m_zip && unzGetCurrentFileInfo(m_zip,NULL, nameBuf, sizeof(nameBuf), NULL, 0, NULL, 0) == UNZ_OK)
	{
		return nameBuf;
	}
	else
		return "";
}

uint32_t ZPackageZip::CurrentFileSize()
{
	unz_file_info unzinfo;
	if (m_zip && unzGetCurrentFileInfo(m_zip, &unzinfo, NULL, 0, NULL, 0, NULL, 0) == UNZ_OK)
	{
		return unzinfo.uncompressed_size;
	}
	else
		return 0;
}

bool ZPackageZip::OpenCurrentFile()
{
	if (m_zip)
		return unzOpenCurrentFile(m_zip) == UNZ_OK;
	else
		return false;
}

bool ZPackageZip::OpenCurrentFilePassword(const char* password)
{
	if (m_zip)
		return unzOpenCurrentFilePassword(m_zip, password) == UNZ_OK;
	else
		return false;
}

bool ZPackageZip::CloseCurrentFile()
{
	if (m_zip)
		return unzCloseCurrentFile(m_zip) == UNZ_OK;
	else
		return false;
}

int ZPackageZip::Read(void* buf, unsigned len)
{
	if (m_zip)
		return unzReadCurrentFile(m_zip, buf, len);
	else
		return -1;
}

ZBufferPtr ZPackageZip::ReadCurrentFileData() {
	uint32_t len = CurrentFileSize();
	if (len > 0) {
		ZBufferPtr buffer = ZBuffer::Create(len);
		if(buffer)
			Read(buffer->data(), buffer->size());
		return buffer;
	}
	return NULL;
}

long ZPackageZip::Tell()
{
	if (m_zip)
		return unztell(m_zip);
	else
		return -1;
}


bool ZPackageZip::Eof()
{
	if (m_zip)
		return (bool)unzeof(m_zip);
	else
		return false;
}


unsigned long ZPackageZip::GetOffset()
{
	if (m_zip)
		return unzGetOffset(m_zip);
	else
		return 0;
}

bool ZPackageZip::SetOffset(unsigned long offset)
{
	if (m_zip)
		return unzSetOffset(m_zip, offset) == UNZ_OK;
	else
		return false;
}




}//namespace

